﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using SnippetDoc.Entities;

namespace SnippetDoc.Utils
{
    public class SnippetFactory
    {
        private CodeSampleInterpreter codeSampleInterpreter;

        public SnippetFactory()
        {
            codeSampleInterpreter = new CodeSampleInterpreter();
        }

        public IEnumerable<Snippet> CreateSnippet(XDocument snippetXDoc)
        {
            if (snippetXDoc == null)
            {
                throw new ArgumentNullException("snippetXDoc", "Argument cannot be null!");
            }

            XNamespace ns = "http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet";

            var snippets = from s in snippetXDoc.Descendants(ns + "CodeSnippet")
                           select new Snippet
                           {
                               Title = s.Element(ns + "Header").Element(ns + "Title").Value,
                               Author = s.Element(ns + "Header").Element(ns + "Author").Value,
                               Description = s.Element(ns + "Header").Element(ns + "Description").Value,
                               Shortcut = s.Element(ns + "Header").Element(ns + "Shortcut").Value,
                               CodeSample = CreateCodeSample(s.Element(ns + "Snippet"), ns)
                           };

            return snippets.ToList<Snippet>();
        }

        private string CreateCodeSample(XElement element, XNamespace ns)
        {
            SnippetDetail snippetDetail = new SnippetDetail();

            var declarations = from d in element.Descendants(ns + "Literal")
                              select new VariableDeclaration
                              {
                                    Id = d.Element(ns + "ID").Value,
                                    DefaultValue = d.Element(ns + "Default").Value
                              };

            snippetDetail.VariableDeclarations = declarations.ToList<VariableDeclaration>();
            snippetDetail.SnippetTemplate = element.Element(ns+"Code").Value;

            return codeSampleInterpreter.InterpreteSnippetTemplate(snippetDetail);
        }
    }
}
